﻿// ChangeWallpapers.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <Windows.h>
#include <iostream>
#include <string>
#include <sstream>


using namespace std;

const string strLocalDirectory = "C:\\Users\\augus\\Pictures\\Wall\\";

enum class WallpaperStyle
{
	Tile,    //平铺
	Center,  //居中
	Stretch, //拉伸
	Fit,     //适应
	Fill     //填充
};

//   FUNCTION: SetDesktopWallpaper(WallpaperStyle)
//
//   PURPOSE: Set the desktop wallpaper.
//
//   PARAMETERS: 
//   * pszFile - Path of the wallpaper
//   * style - Wallpaper style
//
HRESULT SetDesktopWallpaper(WallpaperStyle style)
{
    HRESULT hr = S_OK;

    //设置壁纸风格和展开方式
    //在Control Panel\Desktop中的两个键值将被设置
    // TileWallpaper
    //  0: 图片不被平铺 
    //  1: 被平铺 
    // WallpaperStyle
    //  0:  0表示图片居中，1表示平铺
    //  2:  拉伸填充整个屏幕
    //  6:  拉伸适应屏幕并保持高度比
    //  10: 图片被调整大小裁剪适应屏幕保持纵横比

    //以可读可写的方式打开HKCU\Control Panel\Desktop注册表项
    HKEY hKey = NULL;
    hr = HRESULT_FROM_WIN32(RegOpenKeyEx(HKEY_CURRENT_USER,
        L"Control Panel\\Desktop", 0, KEY_READ | KEY_WRITE, &hKey));
    if (S_OK == hr)
    {
        PWSTR pszWallpaperStyle = (PWSTR)L"0";
        PWSTR pszTileWallpaper = (PWSTR)L"0";

        switch (style)
        {
        case WallpaperStyle::Tile:
            pszWallpaperStyle = (PWSTR)L"0";
            pszTileWallpaper = (PWSTR)L"1";
            break;

        case WallpaperStyle::Center:
            pszWallpaperStyle = (PWSTR)L"0";
            pszTileWallpaper = (PWSTR)L"0";
            break;

        case WallpaperStyle::Stretch:
            pszWallpaperStyle = (PWSTR)L"2";
            pszTileWallpaper = (PWSTR)L"0";
            break;

        case WallpaperStyle::Fit: // (Windows 7 and later)
            pszWallpaperStyle = (PWSTR)L"6";
            pszTileWallpaper = (PWSTR)L"0";
            break;

        case WallpaperStyle::Fill: // (Windows 7 and later)
            pszWallpaperStyle = (PWSTR)L"10";
            pszTileWallpaper = (PWSTR)L"0";
            break;
        }

        // 设置 WallpaperStyle 和 TileWallpaper 到注册表项.
        DWORD cbData = lstrlen(pszWallpaperStyle) * sizeof(*pszWallpaperStyle);
        hr = HRESULT_FROM_WIN32(RegSetValueEx(hKey, L"WallpaperStyle", 0, REG_SZ,
            reinterpret_cast<const BYTE*>(pszWallpaperStyle), cbData));
        if (S_OK == hr)
        {
            cbData = lstrlen(pszTileWallpaper) * sizeof(*pszTileWallpaper);
            hr = HRESULT_FROM_WIN32(RegSetValueEx(hKey, L"TileWallpaper", 0, REG_SZ,
                reinterpret_cast<const BYTE*>(pszTileWallpaper), cbData));
        }

        RegCloseKey(hKey);
    }
    return hr;
}

void changeWallpapers(string path) {
	stringstream fullPath;
	fullPath << strLocalDirectory << path;
    //通过调用Win32 API函数SystemParametersInfo 设置桌面壁纸
    /************************************************
    之前我们已经设置了壁纸的类型，但是壁纸图片的实际文件路径还没
    设置。SystemParametersInfo 这个函数位于user32.dll中，它支持
    我们从系统中获得硬件和配置信息。它有四个参数，第一个指明调用这
    个函数所要执行的操作，接下来的两个参数指明将要设置的数据，依据
    第一个参数的设定。最后一个允许指定改变是否被保存。这里第一个参数
    我们应指定SPI_SETDESKWALLPAPER，指明我们是要设置壁纸。接下来是
    文件路径。在Vista之前必须是一个.bmp的文件。Vista和更高级的系统
    支持.jpg格式
    *************************************************/
    //SPI_SETDESKWALLPAPER参数使得壁纸改变保存并持续可见。
	// BOOL SystemParametersInfoA(UINT  uiAction, UINT  uiParam, PVOID pvParam, UINT  fWinIni);
	// SPIF_UPDATEINIFILE   将新的系统范围的参数设置写入用户配置文件。
	// SPIF_SENDCHANGE      更新用户配置文件后广播WM_SETTINGCHANGE消息。
    if (!SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, (PVOID)fullPath.str().c_str(), SPIF_UPDATEINIFILE | SPIF_SENDCHANGE)) {
        cout << "Failed to load " << fullPath.str() << "set! \n";
    };
}

int main()
{
    SetDesktopWallpaper(WallpaperStyle::Tile);

    SYSTEMTIME sysTime = { 0 };
    GetLocalTime(&sysTime);
    printf("%d-%02d-%02d %02d:%02d:%02d\n", 
        sysTime.wYear,
        sysTime.wMonth,
        sysTime.wDay,
        sysTime.wHour,
        sysTime.wMinute,
        sysTime.wSecond);

    

	string filePath;
	for (int i = 1; i < 6; i++) {
		filePath = to_string(i) + ".png";
		changeWallpapers(filePath);
		if (i == 5) i = 1;
	}
	return 0;
}



// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件，或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来，若要再次打开此项目，请转到“文件”>“打开”>“项目”并选择 .sln 文件
